<html>
<head><meta charset="utf-8"><title>Infinite recursion · t-compiler/help · Zulip Chat Archive</title></head>
<h2>Stream: <a href="https://rust-lang.github.io/zulip_archive/stream/182449-t-compiler/help/index.html">t-compiler/help</a></h2>
<h3>Topic: <a href="https://rust-lang.github.io/zulip_archive/stream/182449-t-compiler/help/topic/Infinite.20recursion.html">Infinite recursion</a></h3>

<hr>

<base href="https://rust-lang.zulipchat.com">

<head><link href="https://rust-lang.github.io/zulip_archive/style.css" rel="stylesheet"></head>

<a name="224210821"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/182449-t-compiler/help/topic/Infinite%20recursion/near/224210821" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> nyms <a href="https://rust-lang.github.io/zulip_archive/stream/182449-t-compiler/help/topic/Infinite.20recursion.html#224210821">(Jan 27 2021 at 16:52)</a>:</h4>
<p>Recently, I opened a bug (<a href="https://github.com/rust-lang/rust/issues/81316">https://github.com/rust-lang/rust/issues/81316</a>) about infinite recursion causing a stack overflow at runtime, with no compiler warning/error issued. I understand that the related lint is working as intended, but don't understand how the underlying pattern doesn't represent unsoundness in a 100% "safe" Rust program.</p>
<p>Are there situations where this kind of infinite recursion is useful and/or terminates? Are there ways to avoid stack overflows without causing breaking changes in otherwise well-behaving programs?</p>
<p>Thanks in advance for any feedback.</p>



<a name="224211127"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/182449-t-compiler/help/topic/Infinite%20recursion/near/224211127" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Jonas Schievink  [he/him] <a href="https://rust-lang.github.io/zulip_archive/stream/182449-t-compiler/help/topic/Infinite.20recursion.html#224211127">(Jan 27 2021 at 16:54)</a>:</h4>
<p>Why is this unsound? The overflow is caught by the runtime</p>



<a name="224211801"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/182449-t-compiler/help/topic/Infinite%20recursion/near/224211801" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> nyms <a href="https://rust-lang.github.io/zulip_archive/stream/182449-t-compiler/help/topic/Infinite.20recursion.html#224211801">(Jan 27 2021 at 16:59)</a>:</h4>
<p>so, the sigabrt and core dump doesn't cause any memory corruption? Maybe I am confused, and thought the stack overflow was actually overflowing the stack, and not just detecting that an overflow is occurring...</p>



<a name="224211806"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/182449-t-compiler/help/topic/Infinite%20recursion/near/224211806" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> bjorn3 <a href="https://rust-lang.github.io/zulip_archive/stream/182449-t-compiler/help/topic/Infinite.20recursion.html#224211806">(Jan 27 2021 at 16:59)</a>:</h4>
<p>It is impossible to avoid stack overflows without an analysis of the stack usage of every function within a call graph and knowledge about the actual stack size. The actual stack size is only unknown at runtime due to <code>ulimit -s</code> and <code>thread::Builder::stack_size</code>. Analysis of every function would have to omit all possible sources of unbounded recursion, even when in practise the amount of recursion is low enough to not overflow the stack.</p>



<a name="224211913"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/182449-t-compiler/help/topic/Infinite%20recursion/near/224211913" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> bjorn3 <a href="https://rust-lang.github.io/zulip_archive/stream/182449-t-compiler/help/topic/Infinite.20recursion.html#224211913">(Jan 27 2021 at 17:00)</a>:</h4>
<p>It does overflow the stack but due to the combination of stack probes and a stack guard it will always abort.</p>



<a name="224211984"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/182449-t-compiler/help/topic/Infinite%20recursion/near/224211984" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> nyms <a href="https://rust-lang.github.io/zulip_archive/stream/182449-t-compiler/help/topic/Infinite.20recursion.html#224211984">(Jan 27 2021 at 17:00)</a>:</h4>
<p>so, is there memory corruption, or no?</p>



<a name="224212089"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/182449-t-compiler/help/topic/Infinite%20recursion/near/224212089" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Jonas Schievink  [he/him] <a href="https://rust-lang.github.io/zulip_archive/stream/182449-t-compiler/help/topic/Infinite.20recursion.html#224212089">(Jan 27 2021 at 17:01)</a>:</h4>
<p>no</p>



<a name="224212122"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/182449-t-compiler/help/topic/Infinite%20recursion/near/224212122" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Dániel Buga <a href="https://rust-lang.github.io/zulip_archive/stream/182449-t-compiler/help/topic/Infinite.20recursion.html#224212122">(Jan 27 2021 at 17:01)</a>:</h4>
<p>The situation is a bit more muddied on embedded environments where there may or may not be memory  protection - there even a deep call tree can corrupt random memory regions, but well, there isn't really anything to do about that, really.</p>



<a name="224212192"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/182449-t-compiler/help/topic/Infinite%20recursion/near/224212192" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Jonas Schievink  [he/him] <a href="https://rust-lang.github.io/zulip_archive/stream/182449-t-compiler/help/topic/Infinite.20recursion.html#224212192">(Jan 27 2021 at 17:01)</a>:</h4>
<p>there is, you need to link twice <a href="https://github.com/knurling-rs/flip-link">https://github.com/knurling-rs/flip-link</a></p>



<a name="224212318"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/182449-t-compiler/help/topic/Infinite%20recursion/near/224212318" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Jonas Schievink  [he/him] <a href="https://rust-lang.github.io/zulip_archive/stream/182449-t-compiler/help/topic/Infinite.20recursion.html#224212318">(Jan 27 2021 at 17:02)</a>:</h4>
<p>But on hosted platforms, a guard page is used to detect stack overflows before they can do any damage</p>



<a name="224212349"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/182449-t-compiler/help/topic/Infinite%20recursion/near/224212349" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Dániel Buga <a href="https://rust-lang.github.io/zulip_archive/stream/182449-t-compiler/help/topic/Infinite.20recursion.html#224212349">(Jan 27 2021 at 17:02)</a>:</h4>
<p>Oh I forgot about that. My mistake. Remember the time when lld could do that while linking only once? Worked for like 2 weeks <span aria-label="sweat smile" class="emoji emoji-1f605" role="img" title="sweat smile">:sweat_smile:</span></p>



<a name="224212523"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/182449-t-compiler/help/topic/Infinite%20recursion/near/224212523" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Mario Carneiro <a href="https://rust-lang.github.io/zulip_archive/stream/182449-t-compiler/help/topic/Infinite.20recursion.html#224212523">(Jan 27 2021 at 17:03)</a>:</h4>
<p>You could also do bounds checking in the function prologue, although that's definitely not zero cost</p>



<a name="224213006"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/182449-t-compiler/help/topic/Infinite%20recursion/near/224213006" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> nyms <a href="https://rust-lang.github.io/zulip_archive/stream/182449-t-compiler/help/topic/Infinite.20recursion.html#224213006">(Jan 27 2021 at 17:06)</a>:</h4>
<p><span class="user-mention silent" data-user-id="211727">Jonas Schievink</span> <a href="#narrow/stream/182449-t-compiler.2Fhelp/topic/Infinite.20recursion/near/224212192">said</a>:</p>
<blockquote>
<p>there is, you need to link twice <a href="https://github.com/knurling-rs/flip-link">https://github.com/knurling-rs/flip-link</a></p>
</blockquote>
<p>Is there a generic way to do that across platforms, or do the protections depend too much on memory layout?</p>



<a name="224213609"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/182449-t-compiler/help/topic/Infinite%20recursion/near/224213609" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Jonas Schievink  [he/him] <a href="https://rust-lang.github.io/zulip_archive/stream/182449-t-compiler/help/topic/Infinite.20recursion.html#224213609">(Jan 27 2021 at 17:10)</a>:</h4>
<p>flip-link only works on embedded platforms with static memory layout</p>



<a name="224213664"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/182449-t-compiler/help/topic/Infinite%20recursion/near/224213664" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Jonas Schievink  [he/him] <a href="https://rust-lang.github.io/zulip_archive/stream/182449-t-compiler/help/topic/Infinite.20recursion.html#224213664">(Jan 27 2021 at 17:10)</a>:</h4>
<p>but in theory it is (or could easily be) cross-platform</p>



<a name="224213743"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/182449-t-compiler/help/topic/Infinite%20recursion/near/224213743" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Jonas Schievink  [he/him] <a href="https://rust-lang.github.io/zulip_archive/stream/182449-t-compiler/help/topic/Infinite.20recursion.html#224213743">(Jan 27 2021 at 17:11)</a>:</h4>
<p>it depends on the platform support crate using the "common" symbol/section names, I think</p>



<hr><p>Last updated: Aug 07 2021 at 22:04 UTC</p>
</html>